package com.hotel.front;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.Util;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.labs.repackaged.org.json.JSONException;
import com.google.gson.Gson;
import com.hotel.BL.GenericLogic;
import com.hotel.BL.PaymentLogic;
import com.hotel.BL.ReservationLogic;

import data.Group;
import data.Guest;
import data.Payment;
import data.Reservation;
import data.passingData.GroupData;
import data.passingData.ResultData;

@SuppressWarnings("serial")
public class PaymentService extends HttpServlet{	
	
	//http://localhost:8080/paymentService?func=addPayment&title=1&shortname=1&mode=1&description=aa
	//http://localhost:8080/PaymentService?func=editPayment&&PaymentId=865&title=222222222222222&shortname=1&mode=1&description=aaaaa
	//http://localhost:8080/PaymentService?func=delPayment&PaymentId=865
	//http://localhost:8080/PaymentService?func=changePayment&PaymentId=865
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		try{
			String doClass = req.getParameter("func");
			if(doClass.equals("addPayment")){
				AddPayment(req,resp);
			}else if(doClass.equals("getPayment")){
				GetPaymentGroup(req,resp);
			}
			else if(doClass.equals("calPayment")){
				CalPayment(req,resp);
			}
			else if(doClass.equals("setFolio")){
				SetFolio(req,resp);
			}
			else if(doClass.equals("getPaymentAll")){
				GetPaymentAll(req,resp);
			}
			else if(doClass.equals("getPaymentCost")){
				GetPaymentCost(req,resp);
			}
			else if(doClass.equals("GetFrontPayment")){
				GetFrontPayment(req,resp);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void AddPayment(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, EntityNotFoundException, ParseException
	{	
		Gson gson = new Gson();
		HttpSession session=req.getSession(true);
		long hotelId = 1;
		String sessionCheck = Util.checkSessionEntity(req,resp);
		if(sessionCheck==null||sessionCheck.equals("")){
			resp.setContentType("text/plain; charset=UTF-8");
			resp.getWriter().println(gson.toJson(new ResultData(false)));
			return;
		}
		String counterId = (String) session.getAttribute("currentCounter");
		String description = req.getParameter("description");
		double amount = Double.parseDouble(req.getParameter("amount"));
		String ccNo = req.getParameter("ccNo");
		String ccNo2 = req.getParameter("ccNo2");
		String creditCardId = req.getParameter("creditCardId");
		Date payDate = new Date();
		String payMode = req.getParameter("paymode");
		String paytype = req.getParameter("paytype");
		String parentPaymentString =  req.getParameter("parentPayment");
		long groupId =  Long.parseLong(req.getParameter("groupId"));
		long resId =  Long.parseLong(req.getParameter("resId"));
		String resIdString = req.getParameter("resId");
		String groupIdString = "G"+(req.getParameter("groupId"));
		boolean isSplit = Boolean.parseBoolean(req.getParameter("isSplit"));
		Payment obj = new Payment();
		if(groupId != 0){
			 obj = new PaymentLogic(req,resp).AddPayment( hotelId, amount, Long.parseLong(creditCardId),ccNo, ccNo2, payDate, payMode, paytype,description,parentPaymentString,isSplit,groupIdString,Long.parseLong(counterId));
			//find payment list in group
			ReservationLogic gLogic = new ReservationLogic(req,resp);
			Group g = gLogic.GetGroup(groupId);
			String newList = "";
			if(!g.getPaymentListString().isEmpty()){
				newList = g.getPaymentListString()+","+obj.getId();
			}else{
				newList = String.valueOf(obj.getId());
			}
			gLogic.EditPaymentList(groupId, newList);
		}else{
			 obj = new PaymentLogic(req,resp).AddPayment( hotelId, amount, Long.parseLong(creditCardId),ccNo, ccNo2, payDate, payMode, paytype,description,parentPaymentString,isSplit,resIdString,Long.parseLong(counterId));
			//find payment list in reservation
			ReservationLogic gLogic = new ReservationLogic(req,resp);
			Reservation g = gLogic.GetReservation(resId);
			String newList = "";
			if(!g.getPaymentListString().isEmpty()){
				newList = g.getPaymentListString()+","+obj.getId();
			}else{
				newList = String.valueOf(obj.getId());
			}
			gLogic.EditResPaymentList(resId, newList);
		}
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(obj));
	}
	
	private void GetPaymentGroup(HttpServletRequest req, HttpServletResponse resp)
			throws ParseException, IOException, EntityNotFoundException {
		String paymentId = req.getParameter("paymentId");
		List<Payment> list = new ArrayList<Payment>();
		PaymentLogic paymentLogic = new PaymentLogic(req,resp);
		if(paymentId==null||paymentId.isEmpty())
		{
			list=null;
		}else{
		String [] paymentIdArray = paymentId.trim().split(",");
		for(int i=0;i<paymentIdArray.length;i++){
		Payment g = paymentLogic.GetPayment(Long.parseLong(paymentIdArray[i]));
		list.add(g);
		}
		}
		Gson gson = new Gson();
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(list));
	}
	
	private void CalPayment(HttpServletRequest req, HttpServletResponse resp)
			throws ParseException, IOException, EntityNotFoundException {
		
		HttpSession session=req.getSession(true);
		long hotelId = 1;
		if (session.getAttribute("hotelId") != null)
			hotelId = (Long) session.getAttribute("hotelId");
		String paymentId = req.getParameter("paymentId");
		double g = new PaymentLogic(req,resp).CalculatePayment(paymentId,hotelId);
		Gson gson = new Gson();	
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(g));
	}

private void SetFolio(HttpServletRequest req, HttpServletResponse resp)
		throws ParseException, IOException, EntityNotFoundException {	
	HttpSession session=req.getSession(true);
	Gson gson = new Gson();
	String sessionCheck = Util.checkSessionEntity(req,resp);
	if(sessionCheck==null||sessionCheck.equals("")){
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(new ResultData(false)));
		return;
	}
	long hotelId = 1;
	if (session.getAttribute("hotelId") != null)
		hotelId = (Long) session.getAttribute("hotelId");
	String listPayment = req.getParameter("listPayment");
	String listFolio = req.getParameter("listFolio");
	double pm = new PaymentLogic(req,resp).SetFolio(listFolio, listPayment, hotelId);
	resp.setContentType("text/plain; charset=UTF-8");
	resp.getWriter().println(gson.toJson(pm));
}
	private void GetPaymentAll(HttpServletRequest req, HttpServletResponse resp)
			throws ParseException, IOException, EntityNotFoundException {
		HttpSession session=req.getSession(true);
		long hotelId = 1;
		if (session.getAttribute("hotelId") != null)
			hotelId = (Long) session.getAttribute("hotelId");
		//Date serverDate = new GenericLogic().ServerDateTime(hotelId);
		Date serverDate = Util.GetOnlyDate(new GenericLogic(req,resp).ServerDateTime(hotelId));
		//int serverDateInt = serverDate.getYear()+serverDate.getMonth()+serverDate.getDate();
		PaymentLogic paymentLogic = new PaymentLogic(req,resp);
		HashMap<String,Object> result = new HashMap<String,Object>();
		
		List<Payment> list = paymentLogic.GetAllPayment(hotelId);
		List<GroupData> lgdata = new ArrayList<GroupData>();
		for(Payment payment:list)
		{
			GroupData gData = new GroupData();
			//int DatePaymet = payment.getPayDate().getYear()+payment.getPayDate().getMonth()+payment.getPayDate().getDate();
			Date DatePaymet = Util.GetOnlyDate(payment.getPayDate());
			//if(DatePaymet!= serverDateInt){
			if(!DatePaymet.equals(serverDate)){
				continue;
			}
			String residString = payment.getResIdString().substring(0,1);
			if(residString.equals("G")){
				Group g = null;
				long groupId = Long.parseLong(payment.getResIdString().substring(1,payment.getResIdString().length()));
				ReservationLogic gLogic = new ReservationLogic(req,resp);
				g = gLogic.GetReservationGroup(groupId);
				if(g!=null){
				gData.setName(g.getGuest().getFirstName());
				gData.setLastname(g.getGuest().getLastName());
				gData.setPayment(payment.getAmount());
				gData.setPaydate(payment.getPayDate());
				lgdata.add(gData);
				}
			}else{
				Reservation res = payment.getResId();
				// CHeck Group
				if(!res.getGuestString().equals("0")){
					Guest g = res.getGuest();
					gData.setName(g.getFirstName());
					gData.setLastname(g.getLastName());
					gData.setRoomname(res.getRoom().getRoomName());
					gData.setPayment(payment.getAmount());
					gData.setPaydate(payment.getPayDate());
					lgdata.add(gData);
				}
				
			}
		}
		result.put("PaymentList", lgdata);
		//May be change to query only today
		List<Payment> allPayment = paymentLogic.GetAllPayment(hotelId);
		double paymentAmount = 0;
		for(Payment payment:allPayment){
			//int DatePaymet = payment.getPayDate().getYear()+payment.getPayDate().getMonth()+payment.getPayDate().getDate();
			Date DatePaymet = Util.GetOnlyDate(payment.getPayDate());
			//if(DatePaymet!=serverDateInt){
			if(!DatePaymet.equals(serverDate)){
				continue;
			}
			paymentAmount+=payment.getAmount();
		}
		result.put("PaymentAmount", paymentAmount);
		Gson gson = new Gson();	
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(result));
	}
	private void GetPaymentCost(HttpServletRequest req, HttpServletResponse resp)
			throws ParseException, IOException, EntityNotFoundException {
		Double sumAmount =0.0;
		HttpSession session=req.getSession(true);
		long hotelId = 1;
		if (session.getAttribute("hotelId") != null)
			hotelId = (Long) session.getAttribute("hotelId");
		//Date serverDate = new GenericLogic().ServerDateTime(hotelId);
		Date serverDate = Util.GetOnlyDate(new GenericLogic(req,resp).ServerDateTime(hotelId));
		//int serverDateInt = serverDate.getYear()+serverDate.getMonth()+serverDate.getDate();
		List<Payment> g = new PaymentLogic(req,resp).GetAllPayment(hotelId);
		for(int i =0;i<g.size();i++){
		String checkGroup = g.get(i).getResIdString().substring(0, 1);
		ReservationLogic gLogic = new ReservationLogic(req,resp);
		Group group = new Group();
			if(checkGroup.equals("G")){
				long groupId = Long.parseLong(g.get(i).getResIdString().substring(1,g.get(i).getResIdString().length()));
				group = gLogic.GetReservationGroup(groupId);
				Date groupDate = group.getDate();
				//int DatePaymet = groupDate.getYear()+groupDate.getMonth()+groupDate.getDate();
				Date DatePaymet = Util.GetOnlyDate(groupDate);
				//if(DatePaymet!=serverDateInt){
				if(!DatePaymet.equals(serverDate)){
					continue;
				}
				sumAmount += g.get(i).getAmount();
			}else{
				Reservation res = new Reservation();
				res = gLogic.GetReservation(Long.parseLong(g.get(i).getResIdString()));
				Date resDate = res.getDate();
				//int DatePaymet = resDate.getYear()+resDate.getMonth()+resDate.getDate();
				Date DatePaymet = Util.GetOnlyDate(resDate);
				//if(DatePaymet!=serverDateInt){
				if(DatePaymet.equals(serverDate)){
					continue;
				}
				sumAmount += g.get(i).getAmount();
			}
		}
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(sumAmount);
		
	}
	
	private void GetFrontPayment(HttpServletRequest req, HttpServletResponse resp) throws IOException{
		HttpSession session=req.getSession(true);
		long hotelId = 1;
		if (session.getAttribute("hotelId") != null)
			hotelId = (Long) session.getAttribute("hotelId");
		PaymentLogic paymentLogic = new PaymentLogic(req,resp);
		HashMap<String,Object> result = new HashMap<String,Object>();
		Date nightAudit = Util.GetOnlyDate(new GenericLogic(req,resp).TodayNightAuditTime(hotelId));
		List<Payment> list = paymentLogic.GetPaymentFromDate(hotelId,nightAudit);
		List<HashMap<String,Object>> lgdata = new ArrayList<HashMap<String,Object>>();
		double paymentAmount = 0;
		for(int i=0,count=0;i<list.size()&&count<10;i++)
		{
			Payment payment = list.get(i);
			//Date paymentDate = Util.GetOnlyDate(payment.getPayDate());
			//if(!nightAudit.equals(paymentDate))
		//		continue;
			String residString = payment.getResIdString().substring(0,1);
			HashMap<String,Object> hash = new HashMap<String,Object>();
			int min = Util.GetMin(payment.getPayDate());
			String minString = (min<10)? "0" + Integer.toString(min) : Integer.toString(min);
			String payTime = Util.GetHour(payment.getPayDate())+ ":" + minString;
			hash.put("t", payTime);
			hash.put("a", payment.getAmount());
			
			paymentAmount+=payment.getAmount();
			
			if(residString.equals("G")){
				long groupId = Long.parseLong(payment.getResIdString().substring(1,payment.getResIdString().length()));
				ReservationLogic gLogic = new ReservationLogic(req,resp);
				Group g = gLogic.GetReservationGroup(groupId);
				hash.put("nm", g.getGuest().getFirstName());
				hash.put("ls", g.getGuest().getLastName());
				hash.put("gId", groupId);
			}
			else{
				Reservation res = payment.getResId();
				if(!res.getGuestString().equals("0")){
					Guest g = res.getGuest();
					hash.put("nm", g.getFirstName());
					hash.put("ls", g.getLastName());
					hash.put("rs", res.getId());
					hash.put("rm", res.getRoom().getRoomName());
				}
			}
			lgdata.add(hash);
			count++;
		}
		result.put("Lst", lgdata);
		result.put("Tl", paymentAmount);
		Gson gson = new Gson();	
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(result));
	}
}
